package com.share.handler;


import com.share.common.enums.HttpStatusEnum;
import com.share.common.result.ResponseResult;
import com.share.domain.SecurityUser;
import com.share.util.common.ResponseUtils;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Slf4j
@Component
public class CustomNoPermissionsAccessDeniedHandler implements AccessDeniedHandler {

    @Override
    public void handle(
            HttpServletRequest request,
            HttpServletResponse response,
            AccessDeniedException accessDeniedException
    ) throws IOException, ServletException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = "anonymous";
        String authorities = "none";

        // 1. 安全地获取 Principal，避免 ClassCastException
        if (authentication != null && authentication.getPrincipal() != null) {
            Object principal = authentication.getPrincipal();

            if (principal instanceof SecurityUser) {
                SecurityUser securityUser = (SecurityUser) principal;
                username = securityUser.getUsername();
                authorities = securityUser.getAuthorities().toString();
            } else if (principal instanceof String) {
                // 如果 Principal 是 String（如用户名），直接使用
                username = (String) principal;
            }
        }

        // 2. 记录无权限访问日志
        log.warn(
                "无权限访问 - IP: {}, 路径: {}, 方法: {}, 用户: {}, 角色: {}, 异常: {}",
                request.getRemoteAddr(),
                request.getRequestURI(),
                request.getMethod(),
                username,
                authorities,
                accessDeniedException.getMessage()
        );

        // 3. 返回响应
        ResponseResult<String> result = ResponseResult.fail(
                HttpStatusEnum.FORBIDDEN.getCode(),
                "没有权限访问该资源"
        );
        ResponseUtils.result(response, result);
    }
}